/* speech_serverd的测试客户端实现*/

#include <gflags/gflags.h>
#include <brpc/channel.h>
#include <functional>
#include <cctype>
#include "logger.hpp"
#include "brpc.hpp"
#include "etcd.hpp"
#include "asr.hpp"
#include "speech.pb.h"
#include "aip-cpp-sdk/speech.h"

DEFINE_bool(run_mode, false, "程序的运行模式，false-调试；true-发布");
DEFINE_string(log_file, "", "发布模式下，用于指定日志的输出文件");
DEFINE_int32(log_level, 0, "发布模式下，用于指定日志输出等级");

DEFINE_string(etcd_host, "127.0.0.1:2379", "服务注册中心地址");
DEFINE_string(base_service, "/service", "服务监控根目录");
DEFINE_string(speech_service, "/service/speech_service", "调用的服务目录");


int main(int argc, char* argv[])
{
    google::ParseCommandLineFlags(&argc, &argv, true);
    ChatSystem::InitLogger(FLAGS_run_mode, FLAGS_log_file, FLAGS_log_level);

    //1. 先去注册中心进行服务的发现---发现speech_server的服务器节点地址信息并实例化通信信道
    //1.1 先构造Rpc整体的服务管理信道类
    ChatSystem::ServiceManager::ptr service_manager = std::make_shared<ChatSystem::ServiceManager>();
    service_manager->declared(FLAGS_speech_service);  //设置需要关心的服务
    auto put_cb = std::bind(&ChatSystem::ServiceManager::onServiceOnline, service_manager.get(), std::placeholders::_1, std::placeholders::_2);
    auto del_cb = std::bind(&ChatSystem::ServiceManager::onServiceOffline, service_manager.get(), std::placeholders::_1, std::placeholders::_2);
    //1.2 构造服务发现对象 
    ChatSystem::Discovery::ptr dclient = std::make_shared<ChatSystem::Discovery>(FLAGS_etcd_host, FLAGS_base_service, put_cb, del_cb);
    
    //1.3 通过Rpc信道管理对象，获取提供Speech服务的信道
    auto channel = service_manager->choose(FLAGS_speech_service);
    if(!channel)
    {
        std::this_thread::sleep_for(std::chrono::seconds(1));
        return -1;
    }
    //4. 发起Speech Rpc调用
    // 2.实例化pb中的SpeechService_Stub类对象；
    ChatSystem::SpeechService_Stub stub(channel.get());
    // 3.发起rpc请求，获取响应进行处理；
    brpc::Controller* cntl = new brpc::Controller;
    ChatSystem::SpeechRecognitionReq req;
    //读取语音文件数据
    std::string file_content;
    aip::get_file_content("16k.pcm", &file_content);
    std::cout << file_content.size() << std::endl;
    req.set_request_id("speech_test");
    req.set_speech_content(file_content);

    ChatSystem::SpeechRecognitionRsp* rsp = new ChatSystem::SpeechRecognitionRsp;

    // google::protobuf::Closure* closure = google::protobuf::NewCallback(callback, cntl, rsp);
    // stub.SpeechRecognition(cntl, &req, rsp, closure);    //rpc异步调用
    // std::cout << "Rpc异步调用结束!" << std::endl;
    // std::this_thread::sleep_for(std::chrono::seconds(1));

    stub.SpeechRecognition(cntl, &req, rsp, nullptr);   //rpc 同步调用
    if(cntl->Failed() == true)
    {
        std::cout << "Rpc 调用失败！" << cntl->ErrorText() << std::endl;
        delete cntl;
	    delete rsp;
        std::this_thread::sleep_for(std::chrono::seconds(1));
        return -1;
    }
    if(rsp->success() == false)
    {
        std::cout << rsp->errmsg() << std::endl;
        return -1;
    }
    std::cout << "收到的响应ID：" << rsp->request_id() << std::endl;
    std::cout << "收到的响应内容：" << rsp->recognition_result() << std::endl;
    //这里是有一定资源泄露的，如果Rpc调用失败，cntl和rsp就都不会delete，最后的方法是使用智能指针管理
    delete cntl;
    delete rsp;

}

